至少兩支隊伍進行錦標賽,其中每一隊都會跟其他所有的隊伍進行一對一比賽。每場比賽贏的加 3 分,輸的加 0 分,不會有平手的情況。累積總分最高的就是錦標賽的獲勝者,題目保證只會有一隊獲勝。
輸入為兩個陣列 competitions 和 results,competitions 是雙層陣列結構,每個元素是每場比賽的兩個隊伍 (字串),results 的相同應索引位置則是該場比賽的結果。例如 competitions[i] 為 [teamA, teamB],results[i] 若為 1 代表 teamA 獲勝,0 則代表 teamB 獲勝。輸出最終獲勝的隊伍。
sample input:
competitions = [
['HTML', 'C#'],
['C#', 'Python'],
['Python', 'HTML']
]
results = [0, 0, 1]
sample output:
'Python' // 三場比賽獲勝的分別是 C#、Python、Python,所以積分為 C# 3 分,Python 6 分
這題屬於情境描述很囉唆,但實際邏輯不會太複雜。簡單來說步驟是:
如果光看以上步驟,很有可能會迴圈過陣列記錄分數,然後最後再迴圈過一次 hash table 來找出最高分隊伍。但如果可以在第一次迴圈的同時也記錄最高分隊伍,就可以稍微優化一下程式碼。
方法是在一開始先初始化變數 bestTeam = '',代表當前最高分隊伍,並先放在 hash table 中,分數訂為 0,以免出現查找不到的錯誤。接著在每一次為獲勝隊伍計分完之後,比較獲勝隊伍與 bestTeam 的分數,如果前者較高,則更新 bestTeam。如此一來,迴圈跑完也就可以直接回傳累積最高分的 bestTeam。
n 為比賽數目 (competitions/ results 的陣列長度)
time: O(n)
k 為隊伍數目
space: O(k) 因為 hash table 中至多會記錄 k + 1 支隊伍的分數,+ 1 是來自於剛剛提到另外設定的 bestTeam 。
function tournamentWinner(competitions, results) {
let bestTeam = '';
const scores = { [bestTeam]: 0 };
for (let i = 0; i < competitions.length; i++) {
// 找出每場比賽獲勝隊伍
const result = results[i];
const [teamA, teamB] = competitions[i];
const winner = result === 1 ? teamA : teamB;
// 獲勝隊伍計分
if (!(winner in scores)) scores[winner] = 0;
scores[winner] += 3;
// 計分後和目前最高分比較
if (scores[winner] > scores[bestTeam]) {
bestTeam = winner;
}
}
return bestTeam;
}
無聊的題外話,sample input 之所以會是程式語言的名稱,是因為原文題目的故事情境是有幾個隊伍要進行演算法錦標賽,看哪一隊寫的演算法最快。那就有點好奇,為什麼這種比賽會有隊伍叫 HTML...還是其實隊名就說明了為什麼他們一場都沒贏過...